#define __LOG4CPP__
#include "../conf/Configuration.h"
#include "../log/Mylog.h"
#include "../online/inc/net/TcpServer.h"
#include "../online/inc/threadpool/Threadpool.h"
#include "../online/inc/task/MyTask.h"
#include "../offline/inc/DirScanner.h"
#include "../libs/SplitTool.hpp"
#include "../offline/inc/RssReader.h"
#include "../offline/inc/PageLib.h"
#include "../offline/inc/WebPageLib.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <set>
#include <functional>

using namespace std;
using namespace SE;

Threadpool* pthreadpool = NULL;
Configuration* Configuration::_pInstance = new Configuration("/home/shen/Documents/RSS_SE/conf/setting.conf");
MyTask mytask(
    Configuration::getpInstance()->getConfigMap()["online_stop_words.utf8"], 
    Configuration::getpInstance()->getConfigMap()["online_NewRipePage_dir"], 
    Configuration::getpInstance()->getConfigMap()["online_Newoffset_dir"], 
    Configuration::getpInstance()->getConfigMap()["online_invertIndex_dir"]
);

void ConnectionCallBack(const TcpConnectionPtr &ptr)
{
    logInfo("Client:", ptr->address(), ": connected.");
    ptr->send("Please Typein Keywords...");
}

void MessageCallBack(const TcpConnectionPtr &ptr)
{
	string msg(ptr->recv());
	size_t pos = msg.find('\n');
	msg = msg.substr(0, pos);
	logInfo("From client:", ptr->address(), ": get -> ", msg);
    //查询网页的任务交给子线程
    pthreadpool->addTask(bind(&MyTask::run, &mytask, msg, ptr));
}

void CloseCallBack(const TcpConnectionPtr &ptr)
{
     logInfo("Client connection closed: ", ptr->address());
}

//从rss语料库解析后导入 网页库 与 偏移库
void Save()
{
    DirScanner rssScanner(Configuration::getpInstance()->getConfigMap()["offline_rss_dir"]);
    RssReader rssReader;
    vector<string> rssFiles = rssScanner.get_absolute_files();
    for (auto &e : rssFiles)
        rssReader.ParseRss(e);
    
    PageLib pageLib(rssScanner, rssReader);
    pageLib.save(
        Configuration::getpInstance()->getConfigMap()["offline_ripePage_dir"], 
        Configuration::getpInstance()->getConfigMap()["offline_offset_dir"]);
}


//从已经建立好的网页库 和 偏移库 中读取到
void Get()
{
    WebPageLib pageLibs(
        Configuration::getpInstance()->getConfigMap()["offline_stop_words.utf8"],
        Configuration::getpInstance()->getConfigMap()["offline_ripePage_dir"],
        Configuration::getpInstance()->getConfigMap()["offline_offset_dir"]);

    pageLibs.storeOnDisk(
        Configuration::getpInstance()->getConfigMap()["offline_NewRipePage_dir"],
        Configuration::getpInstance()->getConfigMap()["offline_Newoffset_dir"], 
        Configuration::getpInstance()->getConfigMap()["offline_invertIndex_dir"]);
}

void Start()
{
    //启动线程池，用于处理任务
    Threadpool threadpool(
        stoi(Configuration::getpInstance()->getConfigMap()["threadNum"]), 
        stoi(Configuration::getpInstance()->getConfigMap()["TaskQueSize"]));
    pthreadpool = &threadpool;
    pthreadpool->start();

    //启动服务器
    TcpServer server(
        Configuration::getpInstance()->getConfigMap()["IP"], 
        stoi(Configuration::getpInstance()->getConfigMap()["port"]));
    server.setConnectionCB(ConnectionCallBack);
    server.setMessageCB(MessageCallBack);
    server.setCloseCB(CloseCallBack);
    server.start();
}

void ErrorMSG()
{
    cout << "Param Error! Please Input Number: " << endl;
    cout << "   1) SAVE for saving the xml files." << endl;
    cout << "   2) GET for getting the query xml." << endl;
    cout << "   3) START for starting the server." << endl;
}

int main(int argc, char* argv[])
{
    Mylog::getInstance().setPriority(INFO);
    if(argc != 2)
        ErrorMSG();
    else if(atoi(argv[1]) == 1)
        Save();
    else if(atoi(argv[1]) == 2)
        Get();
    else if(atoi(argv[1]) == 3)
        Start();
    else 
        ErrorMSG();

    return 0;
} 

